﻿using Microsoft.AspNetCore.SignalR;
using MultiAgentsShared;
using System.Text.Json;

namespace MultiAgentsServer.Scripts.Hubs;

public abstract class SignalRBaseHub(IEventBus eventBus) : Hub
{
    protected readonly IEventBus _eventBus = eventBus;
}

public static class SignalRHubExtension
{
    public static T GetData<T>(this Dictionary<string, object> dictionary, string key)
    {
        if (!dictionary.TryGetValue(key, out object? obj) || obj is not JsonElement jsonElement)
        {
            throw new InvalidOperationException($"Key '{key}' not found or not a JsonElement in the dictionary.");
        }

        if (typeof(T).IsEnum)
        {
            if (jsonElement.ValueKind == JsonValueKind.String)
            {
                string enumString = jsonElement.GetString() ?? throw new InvalidOperationException($"Value for key '{key}' is null.");
                return (T)Enum.Parse(typeof(T), enumString);
            }
            if (jsonElement.ValueKind == JsonValueKind.Number)
            {
                int enumInt = jsonElement.GetInt32();
                return (T)Enum.ToObject(typeof(T), enumInt);
            }
            throw new InvalidOperationException($"Unsupported JSON value kind for enum conversion: {jsonElement.ValueKind}");
        }

        return jsonElement.ValueKind switch
        {
            JsonValueKind.String when typeof(T) == typeof(string) => (T)(object)(jsonElement.GetString() ?? ""),
            JsonValueKind.Number when typeof(T) == typeof(int) => (T)(object)jsonElement.GetInt32(),
            JsonValueKind.Number when typeof(T) == typeof(double) => (T)(object)jsonElement.GetDouble(),
            JsonValueKind.Number when typeof(T) == typeof(float) => (T)(object)((float)jsonElement.GetDouble()),
            JsonValueKind.True or JsonValueKind.False when typeof(T) == typeof(bool) => (T)(object)jsonElement.GetBoolean(),
            JsonValueKind.Object or JsonValueKind.Array =>
                JsonSerializer.Deserialize<T>(jsonElement.GetRawText()) ?? throw new InvalidOperationException($"Deserialization resulted in null for type: {typeof(T).Name}"),
            _ => throw new InvalidOperationException($"Unsupported conversion type: {typeof(T).Name}")
        };
    }
}